﻿// <copyright file="WebservicesAccountAdapter.cs" company="FounderSoftware">
// Copyright (c) 2008 All Right Reserved
// </copyright>
// <author>situyiwen</author>
// <email>situ_yiwen@Founder.com</email>
// <date>2010-12-4</date>
// <summary>Webservices 证书认证适配器类，提供组件认证及统一通信功能</summary>

using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using System.Xml;

namespace SZJT.Framework.Adapter
{
    public class WebservicesCertificateAdapter : IAdapter
    {

        private Type _type;
        private string Uid { get; set; }
        private string UserName { get; set; }
        private string Protocol { get; set; }
        private object ServiceInstance { get; set; }
        private string PublicKey { get; set; }
        private X509Certificate2 LocalCertificate { get; set; }
        private string TaskList { get; set; }
        public string Category
        {
            get { return Constants.CERT_ADAPTER; }
        }
        public string UserId
        {
            get;
            set;
            //get { return Uid; }
        }
        public string PublicKeyString
        {
            get { return PublicKey; }
        }
        public string TaskListString
        {
            get { return TaskList; }
        }

        /// <summary>
        /// 单项数据读取方法
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="dataGuid">数据标识</param>
        /// <param name="dataType">数据类型</param>
        /// <returns>xmlDocument 查询结果</returns>
        public XmlNode GetData(string taskGuid, string dataGuid, string dataType)
        {
            if (string.IsNullOrEmpty(taskGuid) || string.IsNullOrEmpty(dataType))
            {
                LoggerHelper.WriteCodePointInfo("输入参数有空值!");
                return null;
            }
            if (string.IsNullOrEmpty(Uid))
            {
                LoggerHelper.WriteCodePointInfo("未能获取调用组件账号");
                return null;
            }
            if (string.IsNullOrEmpty(Protocol))
            {
                LoggerHelper.WriteCodePointInfo("适配器未初始化");
                return null;
            }
            if (null == ServiceInstance)
                ServiceInstance = WebServiceHelper.CallbackWebService(Protocol, out _type);

            if (null == ServiceInstance)
            {
                LoggerHelper.WriteCodePointInfo("创建Webservices代理类失败");
                return null;
            }
            var methodInstance = _type.GetMethod(Constants.GET_METHOD_NAME);
            var serviceResult = methodInstance.Invoke(ServiceInstance, new object[] { Uid, taskGuid, dataGuid, dataType });
            if (null == serviceResult || string.IsNullOrEmpty(serviceResult.ToString()))
            {
                LoggerHelper.WriteCodePointInfo("调用Webservices代理类失败");
                return null;
            }
            var result = new XmlDocument();
            result.LoadXml(serviceResult.ToString());
            return result;
        }
        /// <summary>
        /// 数据写入方法
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="dataGuid">数据标识</param>
        /// <param name="dataType">数据类型</param>
        /// <param name="xmlData">写入字符串</param>
        /// <returns>int 写入结果</returns>
        public int SetData(string taskGuid, string dataGuid, string dataType, XmlNode xmlData)
        {
            if (string.IsNullOrEmpty(taskGuid) || string.IsNullOrEmpty(dataGuid) || string.IsNullOrEmpty(dataType) || null == xmlData)
            {
                LoggerHelper.WriteCodePointInfo("输入参数有空值");
                return -99;
            }
            //if (null == HttpContext.Current)
            //{
            //    LoggerHelper.WriteCodePointInfo("HttpContext初始化失败");
            //    return -99;
            //}
            if (taskGuid.Equals(Constants.ORG_GUID) && dataGuid.Equals(Constants.INIT_GUID) && dataType.Equals(Constants.INIT_TYPE) && string.IsNullOrEmpty(Uid))
            {
                return InitAdapter(xmlData);
            }
            if (string.IsNullOrEmpty(Protocol))
            {
                LoggerHelper.WriteCodePointInfo("代理类初始化失败");
                return -99;
            }
            if (null == ServiceInstance)
                ServiceInstance =
                    WebServiceHelper.CallbackWebService(Protocol, out _type);
            if (null == ServiceInstance)
            {
                LoggerHelper.WriteCodePointInfo("创建Webservices代理类失败");
                return -99;
            }
            var methodInstance = _type.GetMethod(Constants.SET_METHOD_NAME);
            var serviceResult = methodInstance.Invoke(ServiceInstance, new object[] { Uid, taskGuid, dataGuid, dataType, xmlData.OuterXml });
            if (null == serviceResult)
            {
                LoggerHelper.WriteCodePointInfo("调用Webservices代理类失败");
                return -99;
            }
            return (Convert.ToInt32(serviceResult));
        }
        /// <summary>
        /// 初始化适配器
        /// </summary>
        /// <param name="xmlData">初始化配置信息</param>
        /// <returns>int 初始化结果</returns>
        public int InitAdapter(XmlNode xmlData)
        {
            //if (string.IsNullOrEmpty(PublicKeyString))
            //{
            //    if (GetServerInfo())
            //    {
            //        LoggerHelper.WriteCodePointInfo("成功获取平台基础信息");
            //        return 0;
            //    }
            //    LoggerHelper.WriteCodePointInfo("获取平台基础信息失败");
            //    return -99;
            //}
            
            var certificationInfo = GetCertificationInfo(xmlData);
            if (string.IsNullOrEmpty(certificationInfo))
            {
                LoggerHelper.WriteCodePointInfo("初始化参数不正确");
                return -99;
            }
            if (null == ServiceInstance)
                ServiceInstance = WebServiceHelper.CallbackWebService(Protocol, out _type);
            if (null == ServiceInstance)
            {
                LoggerHelper.WriteCodePointInfo("创建Webservices代理类失败");
                return -99;
            }
            var method = _type.GetMethod(Constants.TRANSFORM_DATA);
            var result = method.Invoke(ServiceInstance, new object[] { Uid, Constants.ORG_GUID, certificationInfo });
            if (null == result)
            {
                LoggerHelper.WriteCodePointInfo("调用Webservices代理类失败");
                return -99;
            }
            var orgService = new XmlDocument();
            try
            {
                orgService.LoadXml(result.ToString());
            }
            catch (XmlException e)
            {
                LoggerHelper.WriteStackTraceInfo("xml读取异常:" + e.StackTrace);
                return -99;
            }
            try
            {
                var reader = XmlReader.Create(new StringReader(orgService.InnerXml));
                while (reader.Read())
                {
                    if (reader.Name != "UserID") continue;
                    Uid = LoginTicket.DecryptByPrivateKey(LocalCertificate, reader.ReadString());
                }
                if (string.IsNullOrEmpty(Uid))
                {
                    LoggerHelper.WriteCodePointInfo("组件验证失败，组件未注册到系统数据库中");
                    return -99;
                }
                //if (null != HttpContext.Current.Session)
                //    HttpContext.Current.Session.Add(UserName, Uid);
                //else
                //    HttpContext.Current.Application.Add(UserName, Uid);
                LoggerHelper.WriteStatusInfo("组织机构组件初始化成功");
                return 0;
            }
            catch (XmlException e)
            {
                LoggerHelper.WriteStackTraceInfo("xml读取UserId异常" + e.StackTrace);
                return -99;
            }
        }
        /// <summary>
        /// 复杂查询方法
        /// </summary>
        /// <param name="taskGuid">应用标识</param>
        /// <param name="xmlTransform">查询输入字符串</param>
        /// <returns>xmlDoucument查询结果</returns>
        public XmlNode TransformData(string taskGuid, XmlNode xmlTransform)
        {
            if (string.IsNullOrEmpty(taskGuid) || null == xmlTransform)
            {
                LoggerHelper.WriteCodePointInfo("输入参数有空值!");
                return null;
            }
            if (string.IsNullOrEmpty(Uid))
            {
                LoggerHelper.WriteCodePointInfo("未能获取调用组件账号");
                return null;
            }
            if (string.IsNullOrEmpty(Protocol))
            {
                LoggerHelper.WriteCodePointInfo("适配器初始化失败");
                return null;
            }
            if (null == ServiceInstance)
                ServiceInstance =
                    WebServiceHelper.CallbackWebService(Protocol, out _type);
            if (null == ServiceInstance)
            {
                LoggerHelper.WriteCodePointInfo("创建Webservices代理类失败");
                return null;
            }
            var methodInstance = _type.GetMethod(Constants.TRANSFORM_DATA);
            var serviceResult = methodInstance.Invoke(ServiceInstance, new object[] { Uid, taskGuid, xmlTransform.OuterXml });
            if (null == serviceResult)
            {
                LoggerHelper.WriteCodePointInfo("调用Webservices代理类失败");
                return null;
            }
            var result = new XmlDocument();
            result.LoadXml(serviceResult.ToString());
            return result;
        }
        /// <summary>
        /// 获取初始化参数字符串
        /// </summary>
        /// <param name="xmlDoc">初始化参数字符串</param>
        /// <returns>认证字符串</returns>
        private string GetCertificationInfo(XmlNode xmlDoc)
        {
            var protocol = xmlDoc.SelectSingleNode("Protocol").InnerText;
            if (string.IsNullOrEmpty(protocol))
            {
                LoggerHelper.WriteCodePointInfo("初始化参数未填写服务协议地址信息");
                return string.Empty;
            }
            Protocol = protocol;
            GetServerInfo();
            var encryptTime = LoginTicket.EncryptByPublicKey(PublicKey, DateTime.Now.ToString());
            var userName = xmlDoc.SelectSingleNode("UserName").InnerText;
            if (string.IsNullOrEmpty(userName))
            {
                LoggerHelper.WriteCodePointInfo("初始化参数未填写账户名信息");
                return string.Empty;
            }
            UserName = userName;
            userName = LoginTicket.EncryptByPublicKey(PublicKey, userName);
            var fnidValue = xmlDoc.SelectSingleNode("Certificate/FindValue").InnerText;
            if (string.IsNullOrEmpty(fnidValue))
            {
                LoggerHelper.WriteCodePointInfo("初始化参数未填写证书名称信息");
                return string.Empty;
            }
            var fnidType = Convert.ToString(xmlDoc.SelectSingleNode("Certificate/FindType").InnerText);
            var storeName = Convert.ToString(xmlDoc.SelectSingleNode("Certificate/StoreName").InnerText);
            var storeLocation = Convert.ToString(xmlDoc.SelectSingleNode("Certificate/StoreLocation").InnerText);
            LocalCertificate = LoginTicket.GetLocalCert(fnidValue, fnidType, storeName, storeLocation);
            if (null==LocalCertificate)
            {
                LoggerHelper.WriteCodePointInfo("获取本地证书失败");
                return string.Empty;
            }
            return LoginTicket.CreateCertXml(Constants.ORG_GUID, userName, encryptTime);
        }

        /// <summary>
        /// 获取平台基础信息
        /// </summary>
        /// <returns>是否获取成功</returns>
        private bool GetServerInfo()
        {
            if (null == ServiceInstance)
                ServiceInstance = WebServiceHelper.CallbackWebService(Protocol, out _type);
            if (null == ServiceInstance)
            {
                throw new Exception("创建Webservices代理类失败");
            }
            var method = _type.GetMethod(Constants.GET_METHOD_NAME);
            var result = method.Invoke(ServiceInstance,
                                       new object[]
                                           {
                                               string.Empty
                                               , Constants.SERVERINFO_TASK_GUID
                                               , Constants.SERVERINFO_DATA_GUID
                                               , Constants.SERVERINFO_DATA_TYPE
                                           });
            if (null == result)
            {
                LoggerHelper.WriteCodePointInfo("调用Webservices代理类失败");
                return false;
            }
            var orgService = new XmlDocument();
            try
            {
                orgService.LoadXml(result.ToString());
            }
            catch (XmlException e)
            {
                LoggerHelper.WriteStackTraceInfo("xml读取异常:" + e.StackTrace);
                return false;
            }
            try
            {
                var reader = XmlReader.Create(new StringReader(orgService.InnerXml));
                while (reader.Read())
                {
                    if (reader.Name == "PublicKey")
                        PublicKey = reader.ReadString();
                    if (reader.Name == "TaskList")
                        TaskList = reader.ReadString();
                }
                if (string.IsNullOrEmpty(PublicKey)||string.IsNullOrEmpty(TaskList))
                {
                    LoggerHelper.WriteCodePointInfo("未能获取公钥或平台任务列表！");
                    return false;
                }
            }
            catch (XmlException e)
            {
                LoggerHelper.WriteStackTraceInfo("xml读取公钥或平台任务列表异常" + e.StackTrace);
                return false;
            }
            return true;
        }
        
    }
}
